import axios from 'axios';
import crypto from 'crypto';

interface WechatConfig {
  appId: string;
  appSecret: string;
}

interface AccessTokenResponse {
  access_token: string;
  expires_in: number;
}

interface TicketResponse {
  ticket: string;
  expires_in: number;
}

export class WechatService {
  private config: WechatConfig;
  private accessToken: string | null = null;
  private accessTokenExpires: number = 0;
  private ticket: string | null = null;
  private ticketExpires: number = 0;

  constructor() {
    this.config = {
      appId: process.env.WxAppID || '',
      appSecret: process.env.WxAppSecret || '',
    };
  }

  // 获取Access Token
  private async getAccessToken(): Promise<string> {
    const now = Date.now();
    
    if (this.accessToken && now < this.accessTokenExpires) {
      return this.accessToken;
    }

    try {
      const response = await axios.get<AccessTokenResponse>(
        'https://api.weixin.qq.com/cgi-bin/token',
        {
          params: {
            grant_type: 'client_credential',
            appid: this.config.appId,
            secret: this.config.appSecret,
          },
        }
      );

      this.accessToken = response.data.access_token;
      this.accessTokenExpires = now + (response.data.expires_in - 300) * 1000; // 提前5分钟过期

      return this.accessToken;
    } catch (error) {
      console.error('获取微信Access Token失败:', error);
      throw new Error('获取微信Access Token失败');
    }
  }

  // 获取JS-SDK Ticket
  private async getTicket(): Promise<string> {
    const now = Date.now();
    
    if (this.ticket && now < this.ticketExpires) {
      return this.ticket;
    }

    try {
      const accessToken = await this.getAccessToken();
      const response = await axios.get<TicketResponse>(
        'https://api.weixin.qq.com/cgi-bin/ticket/getticket',
        {
          params: {
            access_token: accessToken,
            type: 'jsapi',
          },
        }
      );

      this.ticket = response.data.ticket;
      this.ticketExpires = now + (response.data.expires_in - 300) * 1000; // 提前5分钟过期

      return this.ticket;
    } catch (error) {
      console.error('获取微信Ticket失败:', error);
      throw new Error('获取微信Ticket失败');
    }
  }

  // 生成签名
  private generateSignature(ticket: string, nonceStr: string, timestamp: number, url: string): string {
    const string1 = `jsapi_ticket=${ticket}&noncestr=${nonceStr}&timestamp=${timestamp}&url=${url}`;
    return crypto.createHash('sha1').update(string1).digest('hex');
  }

  // 获取JS-SDK配置
  async getJSSDKConfig(url: string) {
    try {
      const ticket = await this.getTicket();
      const nonceStr = Math.random().toString(36).substr(2, 15);
      const timestamp = Math.floor(Date.now() / 1000);
      const signature = this.generateSignature(ticket, nonceStr, timestamp, url);

      return {
        appId: this.config.appId,
        timestamp,
        nonceStr,
        signature,
      };
    } catch (error) {
      console.error('获取JS-SDK配置失败:', error);
      throw new Error('获取JS-SDK配置失败');
    }
  }
}

export const wechatService = new WechatService();
